/*

*/ 

#include <string>
#include <iostream>
/*
1.类的作用:
添加一个构造函数令用户能够定义屏幕的尺寸和内容,以及其他两个成员,分别负责移动光标和读取给定位置的字符;

*/
class Screen {
public:
// 使用类型别名等价的声明一个类型名字
    typedef std::string::size_type pos;
	Screen() = default;  // 因为Screen有另一个构造函数, 所以本函数是必需的
	// cursor被其类内初始值初始化为0
    Screen(pos ht, pos wd, char c): height(ht), width(wd), 
	                                contents(ht * wd, c) { }
	friend class Window_mgr;
    Screen(pos ht = 0, pos wd = 0): 
       cursor(0), height(ht), width(wd), contents(ht * wd, ' ') { }
    char get() const              // get the character at the cursor
	    { return contents[cursor]; }       // implicitly inline
    inline char get(pos ht, pos wd) const; // explicitly inline
	Screen &clear(char = bkground);
private:
	static const char bkground = ' ';
public:
    Screen &move(pos r, pos c);      // can be made inline later
    Screen &set(char);
    Screen &set(pos, pos, char);
    // display overloaded on whether the object is const or not
    Screen &display(std::ostream &os) 
                  { do_display(os); return *this; }
    const Screen &display(std::ostream &os) const
                  { do_display(os); return *this; }
private:
    // function to do the work of displaying a Screen
    void do_display(std::ostream &os) const {os << contents;}
    pos cursor = 0;
    pos height = 0, width = 0;
    std::string contents;
};

Screen &Screen::clear(char c) 
{
	contents = std::string(height*width, c);
	return *this;
}

inline                   // 可以在函数的定义处指定inline
Screen &Screen::move(pos r, pos c)
{
    pos row = r * width; // 计算行的位置
    cursor = row + c;    // 在行内将光标移动到指定的列
    return *this;        // 以左值的形式返回对象
}

char Screen::get(pos r, pos c) const // 在类的内部声明成inline
{
    pos row = r * width;      // 计算行的位置
    return contents[row + c]; // 返回给定列的字符
}

inline Screen &Screen::set(char c) 
{ 
    contents[cursor] = c; // 设置当前光标所在位置的新值
    return *this;         // 将this对象作为左值返回
}
inline Screen &Screen::set(pos r, pos col, char ch)
{
	contents[r*width + col] = ch;  // set specified location to given value
	return *this;                  // return this object as an lvalue
}

